<?php

namespace App\Models;

use Carbon\Carbon;
use http\Exception\RuntimeException;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;

// 资金支出流水
class Fund extends Model
{
    protected $fillable = [
        'type',
        'amount',
        'description',
        'create_admin_id',
        'update_admin_id',
        'user_id',
        'fundable_id',
        'fundable_type',
        'pay_at',
    ];

    const TYPE_RENTAL_INCOME = "type_rental_income";
    const TYPE_PERIODIC_INCOME = "type_periodic_income";
    const TYPE_ONE_TIME_PAYMENT = "type_one_time_payment";
    const TYPE_OTHER_INCOME = "type_other_income";
    const TYPE_DEPOSIT_INCOME = "type_deposit_income";

    const TYPE_RENT_EXPENSE = "type_rent_expense";
    const TYPE_DEPOSIT_EXPENSE = "type_deposit_expense";
    const TYPE_OTHER_EXPENSES = "type_other_expenses";

    public static $typeMap = [
        self::TYPE_RENTAL_INCOME => "租金收入",
        self::TYPE_PERIODIC_INCOME => "周期收入",
        self::TYPE_ONE_TIME_PAYMENT => "一次性收入",
        self::TYPE_DEPOSIT_INCOME => "押金收入",
        self::TYPE_OTHER_INCOME => "其他收入",
        self::TYPE_OTHER_EXPENSES => "其他支出",
        self::TYPE_RENT_EXPENSE => "租金支出",
        self::TYPE_DEPOSIT_EXPENSE => "押金支出",
    ];

    public static $incomeMap = [
        self::TYPE_OTHER_EXPENSES => "其他支出",
        self::TYPE_RENT_EXPENSE => "租金支出",
        self::TYPE_DEPOSIT_EXPENSE => "租金支出",
    ];

    const TYPE_INCOME = "type_income";
    const TYPE_EXPENSES = "type_expenses";

    /**
     * 获取简单的类型
     * @param $type Fund模型的常量
     * @return string
     */
    public static function getSimpleType($type)
    {
        $income = [
            self::TYPE_RENTAL_INCOME,
            self::TYPE_ONE_TIME_PAYMENT,
            self::TYPE_PERIODIC_INCOME,
            self::TYPE_OTHER_INCOME,
            self::TYPE_DEPOSIT_INCOME,
        ];
        $expense = [self::TYPE_RENT_EXPENSE, self::TYPE_OTHER_EXPENSES, self::TYPE_DEPOSIT_EXPENSE];

        if (in_array($type, $income)) {
            return self::TYPE_INCOME;
        }
        if (in_array($type, $expense)) {
            return self::TYPE_EXPENSES;
        }

        return "";
    }

    public static function getIncomeType()
    {
        return [
            self::TYPE_RENTAL_INCOME,
            self::TYPE_PERIODIC_INCOME,
            self::TYPE_ONE_TIME_PAYMENT,
            self::TYPE_OTHER_INCOME,
            self::TYPE_DEPOSIT_INCOME,
        ];
    }

    public static function getExpensesType()
    {
        return [
            self::TYPE_OTHER_EXPENSES,
            self::TYPE_RENT_EXPENSE,
            self::TYPE_DEPOSIT_EXPENSE
        ];
    }

    protected $casts = [
        'pay_at' => 'dateTime',
    ];

    /**
     * 创建资金支出 / 收入流水
     * @param $type
     * @param $amount
     * @param null $user_id
     * @param null $description
     * @param $model
     * @return \Illuminate\Database\Eloquent\Builder|Model
     */
    public static function store($type, $amount, $user_id = null, $description = null)
    {
        if (User::query()->find($user_id)) {
            $user_id = null;
        }

        if (!in_array($type, array_keys(self::$typeMap))) {
            throw new RuntimeException("类型错误：type必须是fund模型中的常量");
        }

        return self::query()->create(
            [
                'user_id' => $user_id,
                'type' => $type,
                'amount' => $amount,
                'description' => $description,
                'create_admin_id' => Auth::guard('admin')->id(),
                'update_admin_id' => Auth::guard('admin')->id(),
            ]
        );
    }

    /**
     * 根据模型，创建资金支出 / 收入流水
     * @param $type
     * @param $amount
     * @param null $user_id
     * @param null $description
     * @param $model
     * @return \Illuminate\Database\Eloquent\Builder|Model
     */
    public static function storeByModel($type, $amount, $model, $user_id, $description = null)
    {

        if (!in_array($type, array_keys(self::$typeMap))) {
            throw new RuntimeException("类型错误：type必须是fund模型中的常量");
        }

        return self::query()->create(
            [
                'user_id' => $user_id,
                'type' => $type,
                'amount' => $amount,
                'description' => $description,
                'create_admin_id' => Auth::guard('admin')->id(),
                'update_admin_id' => Auth::guard('admin')->id(),
                'fundable_type' => get_class($model),
                'fundable_id' => $model->id,
                'pay_at' => Carbon::now(),
            ]
        );
    }

    /**
     * 根据模型，创建资金支出 / 收入流水
     * @param $type
     * @param $amount
     * @param $model
     * @param $user_id
     * @param null $description
     * @return \Illuminate\Database\Eloquent\Builder|Model
     */
    public static function storeNotPayByModel($type, $amount, $model, $user_id, $description = null)
    {

        if (!in_array($type, array_keys(self::$typeMap))) {
            throw new RuntimeException("类型错误：type必须是fund模型中的常量");
        }

        return self::query()->create(
            [
                'user_id' => $user_id,
                'type' => $type,
                'amount' => $amount,
                'description' => $description,
                'create_admin_id' => Auth::guard('admin')->id(),
                'update_admin_id' => Auth::guard('admin')->id(),
                'fundable_type' => get_class($model),
                'fundable_id' => $model->id,
            ]
        );
    }


    public function fundable()
    {
        return $this->morphTo();
    }
}
